"use client";
import {
  ActionType,
  PageContainer,
  ProColumns,
  ProTable,
  ProTableProps,
} from "@ant-design/pro-components";
import { Button, Descriptions, Drawer, message, Space, Tag } from "antd";
import { useRef, useState } from "react";
import { getOperLogListApi, clearOperLogApi } from "@/lib/api/system/log";
import { OperLog } from "@/lib/api/system/log.d";
import { useBoolean, useRequest } from "ahooks";
import { getDictDatasByTypesApi } from "@/lib/api/system/dict";
import { getDictValueEnum } from "@/lib/utils/dict";
import { formatOrderParams } from "@/lib/utils/format";
import { download } from "@/lib/utils/file";

export default function Page() {
  const actionRef = useRef<ActionType>();
  const [open, setOpen] = useBoolean(false);
  const [operInfo, setOperInfo] = useState<OperLog>();
  const { data: dictData } = useRequest(() =>
    getDictDatasByTypesApi(["sys_oper_type", "sys_common_status"]),
  );

  const [operTypeMap, statusMap] = dictData ?? [[], []];

  const { run: clearRun } = useRequest(clearOperLogApi, {
    manual: true,
    onSuccess: () => {
      setTimeout(() => {
        actionRef.current?.reload();
      }, 500);
    },
  });

  const { loading: exportOperlogLoading, run: exportOperlog } = useRequest(
    () => download("/monitor/operlog/export", {}, "operlog.xlsx"),
    {
      manual: true,
      onSuccess: () => {
        message.success("导出成功");
      },
    },
  );

  const colums: ProColumns<OperLog>[] = [
    {
      title: "日志编号",
      dataIndex: "operId",
      key: "operId",
      search: false,
    },
    {
      title: "系统模块",
      dataIndex: "title",
      width: 120,
      key: "title",
    },
    {
      title: "操作类型",
      dataIndex: "businessType",
      key: "businessType",
      width: 100,
      valueEnum: getDictValueEnum(operTypeMap),
      render: (_, record) => {
        return (
          operTypeMap.find(
            (item) => item.dictValue === `${record.businessType}`,
          )?.dictLabel ?? "-"
        );
      },
    },
    {
      title: "操作人员",
      dataIndex: "operName",
      key: "operName",
      sorter: true,
      width: 100,
    },
    {
      title: "部门",
      dataIndex: "deptName",
      key: "deptName",
      search: false,
      width: 100,
    },
    {
      title: "操作地址",
      dataIndex: "operIp",
      key: "operIp",
      ellipsis: true,
      width: 150,
    },
    {
      title: "操作状态",
      dataIndex: "status",
      key: "status",
      width: 100,
      valueEnum: getDictValueEnum(statusMap),
      render: (_, record) => {
        return (
          <Tag color={record.status === 0 ? "success" : "error"}>
            {statusMap.find((item) => item.dictValue === `${record.status}`)
              ?.dictLabel ?? "-"}
          </Tag>
        );
      },
    },
    {
      title: "操作时间",
      dataIndex: "operTime",
      key: "operTime",
      valueType: "dateTime",
      width: 200,
      hideInSearch: true,
      sorter: true,
    },
    {
      title: "创建时间",
      dataIndex: "createdTime",
      valueType: "dateRange",
      hideInTable: true,
      search: {
        transform: (value) => {
          return {
            "params[beginTime]": value[0] + " 00:00:00",
            "params[endTime]": value[1] + " 23:59:59",
          };
        },
      },
    },
    {
      title: "消耗时间",
      dataIndex: "costTime",
      key: "costTime",
      search: false,
      width: 100,
      sorter: true,
      render: (_, record) => {
        return `${record.costTime}毫秒`;
      },
    },
    {
      title: "操作",
      key: "action",
      search: false,
      width: 100,
      render: (_, record) => (
        <Space>
          <Button type="link" onClick={() => viewHandler(record)}>
            详情
          </Button>
        </Space>
      ),
    },
  ];

  const proTableProps: ProTableProps<OperLog, any> = {
    columns: colums,
    rowKey: "operId",
    headerTitle: "操作日志",
    expandable: {
      defaultExpandAllRows: true,
    },
    pagination: {
      pageSize: 10,
    },
    actionRef: actionRef,
    options: {
      fullScreen: true,
    },
    toolBarRender: () => {
      return [
        <Button key="clear" type="primary" onClick={clearRun}>
          清空
        </Button>,
        <Button
          key="export"
          loading={exportOperlogLoading}
          type="primary"
          onClick={exportOperlog}
        >
          导出
        </Button>,
      ];
    },
    request: async (params, sort) => {
      const res = await getOperLogListApi({
        ...params,
        ...formatOrderParams(sort),
      });

      return {
        data: res.rows,
        success: true,
        total: res.total,
      };
    },
    onRequestError(e) {
      message.error(e.message);
    },
  };

  const viewHandler = (operInfo: OperLog) => {
    setOperInfo(operInfo);
    setOpen.setTrue();
  };

  return (
    <PageContainer
      header={{
        title: false,
      }}
    >
      <ProTable {...proTableProps}></ProTable>
      <Drawer
        title="操作日志详情"
        width={800}
        open={open}
        onClose={() => setOpen.setFalse()}
      >
        <Descriptions title="" bordered column={4} labelStyle={{ width: 120 }}>
          <Descriptions.Item label="登录信息" span={4}>
            {operInfo?.operId}
          </Descriptions.Item>
          <Descriptions.Item label="请求信息" span={4}>
            {operInfo?.requestMethod} {operInfo?.operUrl}
          </Descriptions.Item>
          <Descriptions.Item label="操作模块" span={4}>
            {operInfo?.title}
          </Descriptions.Item>
          <Descriptions.Item label="操作方法" span={4}>
            {operInfo?.method}
          </Descriptions.Item>
          <Descriptions.Item label="请求参数" span={4}>
            {operInfo?.operParam}
          </Descriptions.Item>
          <Descriptions.Item label="返回参数" span={4}>
            {operInfo?.jsonResult}
          </Descriptions.Item>
          <Descriptions.Item label="操作状态" span={4}>
            {statusMap.find((item) => item.dictValue === `${operInfo?.status}`)
              ?.dictLabel ?? "-"}
          </Descriptions.Item>
          <Descriptions.Item label="消耗时间" span={4}>
            {operInfo?.costTime} 毫秒
          </Descriptions.Item>
          <Descriptions.Item label="操作时间" span={4}>
            {operInfo?.operTime}
          </Descriptions.Item>
        </Descriptions>
      </Drawer>
    </PageContainer>
  );
}
